﻿#region 참조 네임스페이스

using System;
using System.ComponentModel;
using System.Windows.Forms;
using Skying.ComponentModel;
using Skying.Net.Sockets;

#endregion

namespace UdpServer
{
	public partial class MainForm : Form
	{
		#region 변수

		/// <summary>
		/// 클라이언트의 메시지를 수신하는 UDP 리스너를 나타낸다.
		/// </summary>
		private UdpListener _listener;

		/// <summary>
		/// 로깅을 위한 데이터 그리드 바인딩 리스트를 나타낸다.
		/// </summary>
		private SortableBindingList<Log> _logBindingList;

		#endregion

		#region 생성자/소멸자

		public MainForm()
		{
			this.InitializeComponent();

			this._logBindingList = new SortableBindingList<Log>();

			this.LogDataGridView.DataSource = this._logBindingList;
		}

		#endregion

		#region 로깅

		/// <summary>
		/// 로그 그리드 뷰에 로그를 남긴다.
		/// </summary>
		/// <param name="logString">로그 문자열을 설정한다.</param>
		private void Log(string logString)
		{
			try
			{
				string nowString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff");

				this._logBindingList.Add(new Log(nowString, logString));

				this.LogDataGridView.Sort(this.LogDataGridView.Columns[0], ListSortDirection.Descending);
			}
			catch (Exception error)
			{

			}
		}

		#endregion

		#region 버튼 이벤트

		/// <summary>
		/// Start 버튼이 클릭됐을 때 발생하는 이벤트를 구현한다.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void StartButton_Click(object sender, EventArgs e)
		{
			try
			{
				int portNumber = (int)this.PortNumericUpDown.Value;

				this._listener = new UdpListener(portNumber);

				this._listener.ListeningStarted = (eventArgs) =>
				{
					string logString = string.Format("Listening @ {0}:{1}", this._listener.Address, this._listener.Port);

					this.ListenerStripStatusLabel.Text = logString;

					this.StartButton.Enabled = false;
					this.StopButton.Enabled = true;

					this.Log(logString);
				};

				this._listener.ListeningStopped = (eventArgs) =>
				{
					this.ListenerStripStatusLabel.Text = "Stopped";

					this.StartButton.Enabled = true;
					this.StopButton.Enabled = false;

					this.Log("Stopped");
				};

				this._listener.Received = (eventArgs) =>
				{
					TransferEventArgs result = eventArgs.Result;

					string logString = string.Empty;

					Header header = result.Header;

					switch (result.Header.PacketType)
					{
						case PacketType.Serialized:

							if (header.DataType.Equals(typeof(DateTime).FullName))
							{
								DateTime dataObject = (DateTime)result.DataObject;

								logString = string.Format("[R] - Serialized Object (Type: {0}, Value: {1})", header.DataType, dataObject);
							}

							break;

						case PacketType.Message:

							logString = string.Format("[R] - Message (Value: {0})", result.DataMessage);

							break;

						case PacketType.File:

							break;
					}

					this.Log(logString);
				};

				this._listener.Listen();
			}
			catch (Exception error)
			{

			}
		}

		/// <summary>
		/// Stop 버튼이 클릭됐을 때 발생하는 이벤트를 구현한다.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void StopButton_Click(object sender, EventArgs e)
		{
			try
			{
				if (!this._listener.IsListening) return;

				this._listener.Close();
			}
			catch (Exception error)
			{

			}
		}

		#endregion
	}
}